import {
    openMarket,
    openMask,
    selectModel,
    selectSupportModels,
    selectWeb,
    toggleWeb,
    useConversationActions
} from '@/store/chat.ts';
import {
    Blocks,
    Globe,
    LandPlot,
    Play,
    Search,
    Settings,
    Wand2
} from 'lucide-react';
import { useDispatch, useSelector } from 'react-redux';
import { useTranslation } from 'react-i18next';
import React, { useEffect, useMemo, useRef } from 'react';
import { openDialog } from '@/store/settings.ts';
import { cn } from '@/components/ui/lib/utils.ts';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogHeader,
    DialogTitle,
    DialogTrigger
} from '@/components/ui/dialog.tsx';
import { ScrollArea } from '@/components/ui/scroll-area.tsx';
import { getModelAvatar } from '@/components/home/ModelMarket.tsx';
import { Button } from '@/components/ui/button.tsx';
import Tips from '@/components/Tips.tsx';
import { Model } from '@/api/types.tsx';
import { Input } from '@/components/ui/input.tsx';
import { splitList } from '@/utils/base.ts';

type ChatActionProps = {
    className?: string;
    text?: string;
    children?: React.ReactNode;
    onClick?: () => void;
};
export const ChatAction = React.forwardRef<HTMLDivElement, ChatActionProps>(
    (props, ref) => {
        const { className, text, children, onClick } = props;
        const label = useRef(null);
        const [labelWidth, setLabelWidth] = React.useState(0);

        useEffect(() => {
            if (!label.current) return;

            const target = label.current as HTMLDivElement;
            const width = target.clientWidth || target.offsetWidth;
            setLabelWidth(width);
        }, [text, label]);

        return (
            <div
                className={cn('action chat-action', className)}
                onClick={onClick}
                ref={ref}
                style={{ '--width': `${labelWidth}px` } as React.CSSProperties}
            >
                {children}
                <div className="text" ref={label}>
                    {text}
                </div>
            </div>
        );
    }
);

type WebActionProps = {
    visible: boolean;
};

export function WebAction({ visible }: WebActionProps) {
    const { t } = useTranslation();
    const dispatch = useDispatch();
    const web = useSelector(selectWeb);

    return (
        visible && (
            <ChatAction
                className={cn(web && 'active')}
                text={t('chat.web')}
                onClick={() => dispatch(toggleWeb())}
            >
                <Globe className={cn('h-4 w-4 web', web && 'enable')} />
            </ChatAction>
        )
    );
}

export function SettingsAction() {
    const dispatch = useDispatch();

    return (
        <ChatAction onClick={() => dispatch(openDialog())}>
            <Button variant="outline" size="icon">
                <Settings />
            </Button>
        </ChatAction>
    );
}

export function MarketAction() {
    const { t } = useTranslation();
    const dispatch = useDispatch();

    const current = useSelector(selectModel);
    const supportModels = useSelector(selectSupportModels);

    const [search, setSearch] = React.useState('');
    const [open, setOpen] = React.useState(false);

    const { selected } = useConversationActions();

    const models = useMemo(() => {
        const content = search.trim();
        if (content === '') return supportModels;

        const raw = splitList(search.toLowerCase(), [' ', ',', ';', '-']);
        return supportModels.filter(model => {
            return raw.every(item => {
                return model.name.toLowerCase().includes(item);
            });
        });
    }, [supportModels, search]);

    const event = (model: Model) => {
        selected(model.id);
        setOpen(false);
    };

    return (
        <Dialog open={open} onOpenChange={setOpen}>
            <DialogTrigger asChild>
                <ChatAction>
                    <Button variant="outline" size="icon">
                        <Blocks className={`h-4 w-4`} />
                    </Button>
                </ChatAction>
            </DialogTrigger>
            <DialogContent>
                <DialogHeader>
                    <DialogTitle>{t('market.list')}</DialogTitle>
                    <DialogDescription asChild>
                        <div>
                            <Button
                                size={`default-sm`}
                                className={`mt-2 w-full`}
                                onClick={() => dispatch(openMarket())}
                            >
                                <LandPlot className={`h-4 w-4 mr-2`} />
                                {t('market.go')}
                            </Button>
                            <div className={`flex flex-row mt-4 mb-2`}>
                                <Input
                                    value={search}
                                    onChange={e => setSearch(e.target.value)}
                                    placeholder={t('market.search')}
                                />
                                <Button
                                    className={`ml-2 shrink-0`}
                                    variant={`outline`}
                                    size={`icon`}
                                >
                                    <Search className={`h-4 w-4`} />
                                </Button>
                            </div>
                            <ScrollArea
                                className={`flex flex-col mt-2.5 border rounded-md max-h-[60vh]`}
                            >
                                {models.length > 0 ? (
                                    models.map((model, index) => (
                                        <div
                                            key={index}
                                            onClick={() => event(model)}
                                            className={cn(
                                                'flex sm:flex-row flex-col items-center px-4 py-4 sm:py-2 border-b last:border-none select-none cursor-pointer transition-all hover:bg-background-container',
                                                model.id === current &&
                                                    'bg-background-container'
                                            )}
                                        >
                                            <img
                                                className={`w-6 h-6 border rounded-md`}
                                                src={getModelAvatar(
                                                    model.avatar
                                                )}
                                                alt={''}
                                            />
                                            <div
                                                className={`text-common sm:ml-2 mt-2 sm:mt-0`}
                                            >
                                                {model.name}
                                            </div>
                                            <Tips
                                                className={`hidden sm:inline-block`}
                                            >
                                                {model.id}
                                            </Tips>
                                            <Button
                                                className={cn(
                                                    'ml-auto',
                                                    model.id === current &&
                                                        'text-common'
                                                )}
                                                size={`icon-sm`}
                                                variant={`ghost`}
                                                onClick={() => event(model)}
                                            >
                                                <Play
                                                    className={`h-3.5 w-3.5`}
                                                />
                                            </Button>
                                        </div>
                                    ))
                                ) : (
                                    <div
                                        className={`flex justify-center items-center py-8 select-none`}
                                    >
                                        {t('empty')}
                                    </div>
                                )}
                            </ScrollArea>
                        </div>
                    </DialogDescription>
                </DialogHeader>
            </DialogContent>
        </Dialog>
    );
}

export function MaskAction() {
    const dispatch = useDispatch();
    return (
        <ChatAction onClick={() => dispatch(openMask())}>
            <Button variant="outline" size="icon">
                <Wand2 className={`h-4 w-4`} />
            </Button>
        </ChatAction>
    );
}
